package com.xdap.common.utils;


import com.definesys.mpaas.query.MpaasQuery;
import com.xdap.runtime.service.RuntimeDatasourceService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

@Component
public class AbsDao<T> {
    @Autowired
    private RuntimeDatasourceService runtimeDatasourceService;

    @Autowired
    private Environment environment;

    public Integer save(T t) throws Exception {
        MpaasQuery mpaasQuery = runtimeDatasourceService.buildTenantMpaasQuery(environment.getProperty("spring.datasource.name"));
        mpaasQuery.doInsert(t);
        return 1;
    }

    /**
     * 根据ID获取数据
     *
     * @param t
     * @return
     * @throws Exception
     */
    public T findById(T t) throws Exception {
        MpaasQuery mpaasQuery = runtimeDatasourceService.buildTenantMpaasQuery(environment.getProperty("spring.datasource.name"));
        T result = (T) mpaasQuery.eq("id", getPropertyValue(t, "id").toString()).doQueryFirst(t.getClass());
        return result;
    }
    public List<T> list(List<String> ids ) throws Exception {
        MpaasQuery mpaasQuery = runtimeDatasourceService.buildTenantMpaasQuery(environment.getProperty("spring.datasource.name"));
        List<T> result = null;
        if(CollectionUtils.isNotEmpty(ids)){
            result = (List<T>) mpaasQuery.in("id", ids).doQuery();
        }else{
            result = (List<T>) mpaasQuery.isNotNull("id").doQuery();
        }
        return result;
    }

    public List<T> listByDocIds(List<String> documentIds ) throws Exception {
        MpaasQuery mpaasQuery = runtimeDatasourceService.buildTenantMpaasQuery(environment.getProperty("spring.datasource.name"));
        List<T> result = null;
        if(CollectionUtils.isNotEmpty(documentIds)){
            result = (List<T>) mpaasQuery.in("document_id", documentIds).doQuery(List.class);
        }else{
            result = (List<T>) mpaasQuery.isNotNull("document_id").doQuery(List.class);
        }
        return result;
    }

    /**
     * 更新数据
     *
     * @param t
     * @return
     * @throws Exception
     */
    public Integer update(T t) throws Exception {
        MpaasQuery mpaasQuery = runtimeDatasourceService.buildTenantMpaasQuery(environment.getProperty("spring.datasource.name"));
        mpaasQuery.rowid("id", getPropertyValue(t, "id").toString()).doUpdate(t);
        return 1;
    }
    public Integer saveOrUpdate(T t) throws Exception {
        T byId = this.findById(t);
        if(byId == null){
            save(t);
        }else{
            update(t);
        }
        return 1;
    }

    /**
     * 删除
     *
     * @param t
     * @return
     * @throws Exception
     */
    public Integer delete(T t) throws Exception {
        MpaasQuery mpaasQuery = runtimeDatasourceService.buildTenantMpaasQuery(environment.getProperty("spring.datasource.name"));
        mpaasQuery.rowid("id", getPropertyValue(t, "id").toString()).doDelete(t);
        return 1;
    }


    private static Object getPropertyValue(Object bean, String propertyName) {
        Class clazz = bean.getClass();
        try {
            Field field = null;
            Field[] fields = clazz.getDeclaredFields();
            for (Field f : fields) {
                if (f.getName().equalsIgnoreCase(propertyName)) {
                    field = f;
                    break;
                }
            }
            Method method = clazz.getDeclaredMethod(getGetterName(field.getName(), field.getType()), new Class[]{});
            return method.invoke(bean, new Object[]{});
        } catch (Exception e) {

        }
        return null;

    }

    private static String getGetterName(String propertyName, Class<?> type) {
        String method;
        if (type == Boolean.class || type == boolean.class) {
            if ("is".equalsIgnoreCase(propertyName.substring(0, 2))) {
                return propertyName;
            } else {
                return "is" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
            }
        }
        if (propertyName.length() > 1 && Character.isUpperCase(propertyName.charAt(1))) {
            method = "get" + propertyName;
        } else {
            method = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        }
        return method;
    }

}
